import { mapQuery, mapServiceQuery } from '@/api/map'
import { globalBaseMap } from '@/utils/basemap'
import New from '@/utils/new'
import { getQueryParams } from '@/utils/params'

export default class BasemapManager {
  constructor(viewer, cesium) {
    this._viewer = viewer
    this._Cesium = cesium
    this._basemapIndex = -1
    this._historyImagery = {}
    this._basemapList = [
      {
        pkid: '-1',
        name: '无底图',
        showTerrain: false,
        isDefault: 0,
        filePath: ''
      }
    ]
  }

  get basemapList() {
    return this._basemapList
  }

  get currentBasemapIndex() {
    return this._basemapIndex
  }

  get currentHistoryImagery() {
    return this._historyImagery
  }

  /**
   * 切换底图
   *
   * @param index 底图index
   */
  switchBasemap(index) {
    if (this._basemapIndex !== -1) {
      // 切换底图
      if (this._basemapIndex !== 0) {
        // 如果当前不是无底图，则清除之前的底图
        this._removePreviousHistoryImagery()
      }

      // 加载新底图
      this._basemapIndex = index
      const item = this._basemapList[index]
      console.log('item', item)
      if (item.pkid === '-1') {
        // 无底图
        this._historyImagery = {}
        this.toggleTerrain(false)
        if (
          globalBaseMap['supermap-container'] === this ||
          globalBaseMap['compare-left-container'] ===
            this ||
          globalBaseMap['defaultViewId'] === this
        ) {
          New.$emit('mapIndex', {
            list: [],
            active: {}
          })
        } else if (
          globalBaseMap['compare-container'] === this
        ) {
          New.$emit('mapCompareIndex', {
            list: [],
            active: {}
          })
        }
      } else {
        // 非无底图
        // 为了解决底图切换时，历史影像列表选中状态不更新的问题，重置一下数据
        if (
          globalBaseMap['supermap-container'] === this ||
          globalBaseMap['compare-left-container'] ===
            this ||
          globalBaseMap['defaultViewId'] === this
        ) {
          New.$emit('mapIndex', {
            list: [],
            active: {}
          })
        } else if (
          globalBaseMap['compare-container'] === this
        ) {
          New.$emit('mapCompareIndex', {
            list: [],
            active: {}
          })
        }

        const defaultHistoryImageryIndex =
          this._getDefaultHistoryImageryIndex(item)
        console.log(
          'defaultHistoryImageryIndex',
          item.resourceMapBaseServiceInfos[
            defaultHistoryImageryIndex
          ]
        )
        this.switchHistoryImagery(
          item.resourceMapBaseServiceInfos[
            defaultHistoryImageryIndex
          ].pkid
        )
      }
    } else {
      // 第一次加载
      this._basemapIndex = index
      const item = this._basemapList[index]
      console.log('加载的底图', item)
      if (item.pkid === '-1') {
        // 无底图
        // 什么都不做
      } else {
        // 有底图
        const defaultHistoryImageryIndex =
          this._getDefaultHistoryImageryIndex(item)
        this.switchHistoryImagery(
          item.resourceMapBaseServiceInfos[
            defaultHistoryImageryIndex
          ].pkid
        )
      }
    }
  }

  _getDefaultHistoryImageryIndex(basemap) {
    const index =
      basemap.resourceMapBaseServiceInfos.findIndex(
        (item) => item.isDefault === 1
      )
    return index === -1 ? 0 : index
  }

  _removePreviousHistoryImagery() {
    const previousHistoryImagery = this._historyImagery
    if (
      previousHistoryImagery &&
      previousHistoryImagery.serviceUrl
    ) {
      if (previousHistoryImagery.serviceType === 23) {
        this._viewer.scene.removeVectorTilesMap(
          previousHistoryImagery.serviceName
        )
      } else {
        if (previousHistoryImagery.serviceType !== 27) {
          const firstImagery =
            this._viewer.scene.imageryLayers.get(0)
          this._viewer.scene.imageryLayers.remove(
            firstImagery,
            true
          )
        } else {
          // 三维
          if (previousHistoryImagery.layers) {
            previousHistoryImagery.layers.forEach(
              (layer) => {
                if (layer.imageryProvider) {
                  this._viewer.imageryLayers.remove(
                    layer,
                    true
                  )
                  console.log('移除之前图层', layer)
                }
              }
            )
          }
          if (previousHistoryImagery.name) {
            previousHistoryImagery.name.forEach(
              (nameItem, index) => {
                if (!nameItem) {
                  if (
                    previousHistoryImagery.layers[index]
                      .imageryProvider
                  ) {
                    this._viewer.scene.imageryLayers.remove(
                      previousHistoryImagery.layers[index]
                    )
                  } else if (
                    previousHistoryImagery.layers[index]
                      ._iserrainZ
                  ) {
                    this._viewer.terrainProvider =
                      new Cesium.EllipsoidTerrainProvider(
                        {}
                      )
                  }
                } else {
                  this._viewer.scene.layers.remove(nameItem)
                }
              }
            )
          }
        }
      }
    }
    this._historyImagery = {}
  }

  /**
   * 切换历史影像
   *
   * @param id 历史影像pkid
   */
  switchHistoryImagery(id) {
    this._removePreviousHistoryImagery()
    const basemap = this._basemapList[this._basemapIndex] // 当前底图
    const historyImagery =
      basemap.resourceMapBaseServiceInfos.find(
        (item) => item.pkid === id
      ) // 当前历史影像
    this._historyImagery = historyImagery

    // 默认加载或隐藏地形
    if (historyImagery.terrainUrl) {
      this._viewer.terrainProvider =
        new Cesium.CesiumTerrainProvider({
          url: historyImagery.terrainUrl,
          requestWaterMask: true, // 开启法向量
          requestVertexNormals: true, // 开启水面特效
          isSct: true
        })
      basemap.showTerrain = true
    } else {
      this._viewer.terrainProvider =
        new Cesium.EllipsoidTerrainProvider()
      basemap.showTerrain = false
    }

    if (
      globalBaseMap['supermap-container'] === this ||
      globalBaseMap['compare-left-container'] === this ||
      globalBaseMap['defaultViewId'] === this
    ) {
      New.$emit('mapIndex', {
        list: basemap.resourceMapBaseServiceInfos,
        active: historyImagery
      })
    } else if (
      globalBaseMap['compare-container'] === this
    ) {
      New.$emit('mapCompareIndex', {
        list: basemap.resourceMapBaseServiceInfos,
        active: historyImagery
      })
    }
    if (historyImagery.serviceUrl) {
      switch (historyImagery.serviceType) {
        case 21:
          // WMTS
          this._viewer.scene.imageryLayers.addImageryProvider(
            new Cesium.WebMapTileServiceImageryProvider({
              url: historyImagery.serviceUrl,
              layer: historyImagery.serviceName,
              style: 'default',
              tileMatrixSetID: 'default028mm'
            }),
            0
          )
          break
        case 22:
          // XYZ Tiles
          this._viewer.scene.imageryLayers.addImageryProvider(
            new Cesium.WebMapTileServiceImageryProvider({
              url: historyImagery.serviceUrl,
              layer: historyImagery.serviceName,
              style: 'default',
              tileMatrixSetID: 'default028mm'
            }),
            0
          )
          break
        case 23:
          // 矢量
          this._viewer.scene.addVectorTilesMap({
            url: historyImagery.serviceUrl,
            layer: historyImagery.serviceName
          })
          break
        case 24:
          // WMS
          this._viewer.scene.imageryLayers.addImageryProvider(
            new Cesium.WebMapServiceImageryProvider({
              url: historyImagery.serviceUrl,
              layers: historyImagery.serviceName
            }),
            0
          )
          break
        case 25:
          // ArcGIS
          this._viewer.scene.imageryLayers.addImageryProvider(
            new Cesium.ArcGisMapServerImageryProvider({
              url: historyImagery.serviceUrl
            }),
            0
          )
          break
        case 26:
          // REST
          this._viewer.scene.imageryLayers.addImageryProvider(
            new Cesium.SuperMapImageryProvider({
              url: historyImagery.serviceUrl,
              isSct: true
              // minimumLevel: 0,
              // maximumLevel: 24
            }),
            0
          )
          break
        case 27:
          // 三维
          let url, name
          if (
            historyImagery.serviceUrl.indexOf(
              '/realspace/datas/'
            ) !== -1
          ) {
            url = historyImagery.serviceUrl
            name = historyImagery.serviceName
            const promise =
              this._viewer.scene.addS3MTilesLayerByScp(
                url + '/config',
                {
                  autoSetView: false,
                  name: name
                }
              )
            Cesium.when(promise, (layer) => {
              if (layer) {
                layer.clearMemoryImmediately = true
                layer.residentRootTile = false
                layer.isOverlapDisplayed = false
                layer.orderIndependentTranslucency = true
                // layer.indexedDBSetting.isGeoTilesRootNodeSave = true
                historyImagery.name = [name]
                historyImagery.layer = [layer]
                console.log(
                  '修改name和layer, this._historyImagery',
                  this._historyImagery
                )
              } else {
                console.error('添加失败')
              }
            })
          } else if (
            historyImagery.serviceUrl.indexOf(
              '/realspace/scenes/'
            ) === -1
          ) {
            url = historyImagery.serviceUrl
            name = undefined
            const promise = this._viewer.scene.open(
              url,
              name,
              { autoSetView: false }
            )
            Cesium.when(promise, (layers) => {
              if (layers) {
                const realName = []
                const realLayer = []
                layers.forEach((layer) => {
                  layer.clearMemoryImmediately = true
                  layer.residentRootTile = false
                  layer.isOverlapDisplayed = false
                  layer.orderIndependentTranslucency = true
                  realName.push(layer.name)
                  realLayer.push(layer)
                  if (layer.imageryProvider) {
                    this._viewer.imageryLayers.lowerToBottom(
                      layer
                    )
                  }
                })
                historyImagery.name = realName
                historyImagery.layers = realLayer
                console.log(
                  '修改name和layer, this._historyImagery',
                  this._historyImagery
                )
              } else {
                console.error('添加失败')
              }
            })
          } else {
            url = historyImagery.serviceUrl.substring(
              0,
              historyImagery.serviceUrl.indexOf('/scenes')
            )
            name = decodeURI(
              historyImagery.serviceUrl.substring(
                historyImagery.serviceUrl.indexOf(
                  '/scenes/'
                ) + '/scenes/'.length
              )
            )
            const promise = this._viewer.scene.open(
              url,
              name,
              { autoSetView: false }
            )
            Cesium.when(promise, (layers) => {
              if (layers) {
                const realName = []
                const realLayer = []
                layers.forEach((layer) => {
                  layer.clearMemoryImmediately = true
                  layer.residentRootTile = false
                  layer.isOverlapDisplayed = false
                  layer.orderIndependentTranslucency = true
                  layer.style3D &&
                    (layer.style3D.altitudeMode =
                      Cesium.HeightReference.CLAMP_TO_GROUND)
                  realName.push(layer.name)
                  realLayer.push(layer)
                  // if (layer.imageryProvider) {
                  //   this._viewer.imageryLayers.lowerToBottom(
                  //     layer
                  //   )
                  // }
                })
                // 底图子图层层级最低，所以需要倒序执行循环
                for (
                  let i = layers.length - 1;
                  i >= 0;
                  i--
                ) {
                  if (layers[i].imageryProvider) {
                    this._viewer.imageryLayers.lowerToBottom(
                      layers[i]
                    )
                  }
                }
                historyImagery.name = realName
                historyImagery.layers = realLayer
                console.log(
                  '修改name和layer, this._historyImagery',
                  this._historyImagery
                )
              } else {
                console.error('添加失败')
              }
            })
          }
          break
        case 28:
          const queryParams = getQueryParams(
            historyImagery.serviceUrl
          )
          const tiandituUrl =
            historyImagery.serviceUrl.substring(
              0,
              historyImagery.serviceUrl.indexOf('?')
            )
          console.log(
            'queryParams',
            queryParams,
            tiandituUrl
          )
          this._viewer.scene.imageryLayers.addImageryProvider(
            new Cesium.TiandituImageryProvider({
              mapStyle: queryParams.T,
              token: queryParams.tk,
              url: tiandituUrl
            }),
            0
          )
          break
        default:
          break
      }
      this._viewer.scene.requestRender()
    }
  }

  // 显隐地形
  toggleTerrain(show) {
    if (show) {
      const url = this._historyImagery.terrainUrl
      if (url) {
        this._viewer.terrainProvider =
          new Cesium.CesiumTerrainProvider({
            url: url,
            requestWaterMask: true, // 开启法向量
            requestVertexNormals: true, // 开启水面特效
            isSct: true
          })
      }
    } else {
      this._viewer.terrainProvider =
        new Cesium.EllipsoidTerrainProvider({})
    }
  }

  // 获取底图列表
  async getBasemapList(specialType) {
    if (this._basemapList.length === 1 && !specialType) {
      const { success, data } = await mapQuery({
        pageIndex: 1,
        pageSize: 100,
        specialType: ''
      })
      if (success) {
        console.log('所有底图', data)
        const tempList = data.list.map((item) => {
          return {
            ...item,
            resourceMapBaseServiceInfos: []
          }
        })
        for (let i = 0; i < tempList.length; i++) {
          const tempHistoryList =
            await this.getHistoryImageryList(
              tempList[i].pkid
            )
          tempHistoryList.sort(
            (a, b) => a.orderIndex - b.orderIndex
          )
          tempList[i].resourceMapBaseServiceInfos.push(
            ...tempHistoryList
          )
        }
        this._basemapList.push(...tempList)
      }

      this.switchBasemap(0)
    } else {
      const { success, data } = await mapQuery({
        pageIndex: 1,
        pageSize: 100,
        specialType: specialType
      })
      if (success) {
        console.log('专题图类型默认底图', data)
        const defaultBaseMap = data.list.findIndex(
          (item) => item.isDefault === 1
        )
        console.log('default', defaultBaseMap)
        if (defaultBaseMap !== -1) {
          this.switchBasemap(defaultBaseMap + 1)
        }
      }
    }

    // const defaultBasemapIndex =
    //   this._basemapList.findIndex(
    //     (item) => item.isDefault === 1
    //   )
    // if (defaultBasemapIndex !== -1) {
    //   this.switchBasemap(defaultBasemapIndex)
    // } else {
    //   this.switchBasemap(0)
    // }

    return this._basemapList
  }

  // 获取历史影像列表
  async getHistoryImageryList(id) {
    const { success, data } = await mapServiceQuery(id)
    if (
      success &&
      data.resourceMapBaseServiceInfos &&
      data.resourceMapBaseServiceInfos.length
    ) {
      return data.resourceMapBaseServiceInfos
    }
    return []
  }
}
